package com.services.ws.auditoria;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.Iterator;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.services.ws.auditoria.model.AccesoRequest;
import com.services.ws.auditoria.model.AccesoResponse;

public class LeerDatosUsuarioManager {
	
	private static Logger logger;
	private String 				address;
	private String    			service;
	private static String		url;
	private int 				port;
	private final static String soapEnvelopeStartTag = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ws=\"http://pe/com/claro/esb/services/auditoria/ws\" "
			+ "xmlns:acc=\"http://pe/com/claro/esb/services/auditoria/schemas/accesos/Acceso.xsd\">  <soapenv:Header/>  <soapenv:Body>";
			
	private final static String soapEnvelopeEndTag = "</soapenv:Body></soapenv:Envelope>";
	
	public LeerDatosUsuarioManager(String address, int port, String service) throws Exception 
	{  
		this.address = 	address;
		this.port = 	port;
		this.service = 	service;	
		try{
			logger = LoggerFactory.getLogger(LeerDatosUsuarioManager.class);
		} catch (Exception e){
			System.out.println("The EbsAuditoriaManager logger could not be initialized: " + e.getMessage());
		}
			
		init();
	}
	
	public AccesoResponse leerDatosUsuario(AccesoRequest accesoRequest, final int timeOut) throws SOAPException{
		AccesoResponse accesoResponse = new AccesoResponse();
		StringBuffer msgInfo = new StringBuffer();
		long startTime = 0L;
        long endTime = 0L;
        
        StringBuffer sbRequest = new StringBuffer();
		SOAPConnection conn = null;

		sbRequest.append(soapEnvelopeStartTag);
		sbRequest.append("<ws:leerDatosUsuario>");
		sbRequest.append("<acc:AccesoRequest>");
		sbRequest.append("<acc:usuario>"+accesoRequest.getUsuario()+"</acc:usuario>");
		sbRequest.append("<acc:aplicacion>"+accesoRequest.getAplicacion()+"</acc:aplicacion>");
		sbRequest.append("</acc:AccesoRequest>");
		sbRequest.append("</ws:leerDatosUsuario>");
		sbRequest.append(soapEnvelopeEndTag);
		
		logger.info(sbRequest.toString());
		try{
		MessageFactory mf = MessageFactory.newInstance();
		MimeHeaders headers = new MimeHeaders();
		SOAPMessage smsg = mf.createMessage(headers, new ByteArrayInputStream(sbRequest.toString().getBytes()));
		conn = SOAPConnectionFactory.newInstance().createConnection();
		startTime = System.currentTimeMillis();
		
		URL endpoint = new URL(null, 
				url, 
                new URLStreamHandler() {
                   protected URLConnection openConnection(URL url) throws IOException{  
                	   URL clone_url = new URL(url.toString());
                	   HttpURLConnection clone_urlconnection =(HttpURLConnection) clone_url.openConnection(); 
                       clone_urlconnection.setConnectTimeout(timeOut);
	                   clone_urlconnection.setReadTimeout(timeOut);
                	   return(clone_urlconnection);
                   }
            }); 
		
		SOAPMessage smResponse = conn.call(smsg, endpoint);
		//smResponse.writeTo(System.out);
		endTime = System.currentTimeMillis();
		if(smResponse != null){
			SOAPBody soapBody = smResponse.getSOAPBody();
			Iterator soapBodyIterator = soapBody.getChildElements();
			soapBody = null;
			if(soapBodyIterator.hasNext()){
				SOAPElement soapBodyElement = (SOAPElement) soapBodyIterator.next();
				Iterator getSubIterator = soapBodyElement.getChildElements();
				if(getSubIterator.hasNext()){
					SOAPElement getSubElement = (SOAPElement) getSubIterator.next();
					Iterator payerIterator = getSubElement.getChildElements();
					while(payerIterator.hasNext()){
						SOAPElement payerElement = (SOAPElement) payerIterator.next();
						Iterator subSubElemet = payerElement.getChildElements();
						while(subSubElemet.hasNext()){
							SOAPElement iterates = (SOAPElement) subSubElemet.next();
							//System.out.println(iterates.getTagName()+", "+iterates.getValue());
							if(iterates.getTagName().contains("estado")){
								accesoResponse.setEstado(iterates.getValue());
							}else if(iterates.getTagName().contains("mensaje")){
								accesoResponse.setMensaje(iterates.getValue());
							}else if(iterates.getTagName().contains("AuditoriaItem")){
								Iterator item = iterates.getChildElements();
								if(item.hasNext()){
									SOAPElement items = (SOAPElement) item.next();
									Iterator cap = items.getChildElements();
									//System.out.println("items "+items.getTagName()+", "+items.getValue());
									while(cap.hasNext()){
										SOAPElement caps = (SOAPElement) cap.next();
										if(caps.getTagName().contains("codigo")){
											accesoResponse.setCodigo(caps.getValue());
											break;
										}
									}
								}
							}else if(iterates.getTagName().contains("nombres")){
								accesoResponse.setNombre(iterates.getValue());
							}else if(iterates.getTagName().contains("paterno")){
								accesoResponse.setPaterno(iterates.getValue());
							}
						}
						
					}
				}
			}
			 msgInfo.append("ws-leerDatosUsuario" + "\t");
			 msgInfo.append("[" + accesoRequest.getUsuario() + ","+ accesoRequest.getAplicacion()+"]" + "\t");
	         msgInfo.append("Return Resultado [Estado : " + accesoResponse.getEstado()+ ",\t");
	         msgInfo.append("Mensaje : " + accesoResponse.getMensaje() + "]\t");
	         msgInfo.append("Item [Codigo : " + accesoResponse.getCodigo()+ "]\t");
	         msgInfo.append("Empleado [Nombre : " + accesoResponse.getNombre()+ ",\t");
	         msgInfo.append("ApPaterno : " + accesoResponse.getPaterno()+ "]\n");
	         msgInfo.append("\t");
	         msgInfo.append((endTime - startTime) + "ms\t");
	         logger.info(msgInfo.toString());
		}else{
			 msgInfo.append("Usuario : " + accesoRequest.getUsuario()+ "\t");
		      msgInfo.append("Aplicacion : " + accesoRequest.getAplicacion() + "\t");
		      msgInfo.append("NO OK Response is null" + "\t");
			  msgInfo.append((endTime - startTime) + "ms\t");
			  logger.info(msgInfo.toString());
			  accesoResponse.setEstado("-1");
			  accesoResponse.setMensaje("NO OK Response is null");
			  logger.info(msgInfo.toString());
		}
		
		}catch(IOException ioex){
			endTime = System.currentTimeMillis();
			msgInfo.append("ws-leerDatosUsuario" + "\t");
	        msgInfo.append("[" + accesoRequest.getUsuario() + ","+ accesoRequest.getAplicacion()+"]" + "\t");
	        msgInfo.append("TriacionesGenerico WS\t");
	        msgInfo.append("No OK\t");
	        msgInfo.append("IOException=" + ioex.getMessage() + "\t");
	        msgInfo.append((endTime - startTime) + "ms\n"); 
	        logger.info(msgInfo.toString());
	        accesoResponse.setEstado("-1");
			accesoResponse.setMensaje("IOException=" + ioex.getMessage());
		}catch (SOAPException soapex) {
			endTime = System.currentTimeMillis();
			if(soapex.toString().contains("Message send failed")){
				msgInfo.append("ws-leerDatosUsuario" + "\t");
				msgInfo.append("[" + accesoRequest.getUsuario() + ","+ accesoRequest.getAplicacion()+"]" + "\t");
		        msgInfo.append("ws-leerDatosUsuario WS\t");
		        msgInfo.append("No OK\t");
		        msgInfo.append("TimeOut SOAPException=" + soapex.getMessage() + "\t");
		        msgInfo.append((endTime - startTime) + "ms\n"); 
		        logger.info(msgInfo.toString());
		        accesoResponse.setEstado("-1");
				accesoResponse.setMensaje("TimeOut SOAPException=" + soapex.getMessage());
	        }else{
				msgInfo.append("ws-leerDatosUsuario" + "\t");
				msgInfo.append("[" + accesoRequest.getUsuario() + ","+ accesoRequest.getAplicacion()+"]" + "\t");
		        msgInfo.append("ws-leerDatosUsuario WS\t");
		        msgInfo.append("No OK\t");
		        msgInfo.append("SOAPException=" + soapex.getMessage() + "\t");
		        msgInfo.append((endTime - startTime) + "ms\n"); 
		        accesoResponse.setEstado("-1");
				accesoResponse.setMensaje("SOAPException=" + soapex.getMessage());
		        logger.info(msgInfo.toString());
	        }
		}catch (Exception ex) {
			endTime = System.currentTimeMillis();
			msgInfo.append("ws-leerDatosUsuario" + "\t");
			msgInfo.append("[" + accesoRequest.getUsuario() + ","+ accesoRequest.getAplicacion()+"]" + "\t");
	        msgInfo.append("ws-leerDatosUsuario WS\t");
	        msgInfo.append("No OK\t");
	        msgInfo.append("Exception=" + ex.getMessage() + "\t");
	        msgInfo.append((endTime - startTime) + "ms\n"); 
	        logger.info(msgInfo.toString()); 
	        accesoResponse.setEstado("-1");
			accesoResponse.setMensaje("Exception=" + ex.getMessage());
		}finally{
			conn.close(); // close connection
			conn = null;
		}
		return accesoResponse;
	}
	
	public void init() throws Exception{
		try{
			logger.info("Initializing leerDatosUsuarioManager Web Service Manager...");
			logger.info("leerDatosUsuarioManager Web Service Address = " + address);
			logger.info("leerDatosUsuarioManager Web Service Port = " + port);
			logger.info("leerDatosUsuarioManager Web Service = " + service);
			url = "http://"+ address+":"+port+"/"+service;
			logger.info("leerDatosUsuarioManager URL = "+url);
			logger.info("leerDatosUsuarioManager Web Service Manager initialized successfully");
		} catch (Exception _ex) {
			_ex.printStackTrace();
			throw new Exception("Unable to initialize leerDatosUsuarioManager webservice manager");
		}
	}
	
}
